﻿using Abp.Domain.Repositories;
using Abp.Domain.Services;
using Abp.UI;
using shenghua.Authorization.Users;
using shenghua.Basics;
using shenghua.Marketing.SalesPromotions;
using shenghua.Member.Collection;
using shenghua.Member.Coupons;
using shenghua.Order.Orders.Median;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace shenghua.Commodity.Commodities
{
    public class CommodityManager: DomainService
    {
        private readonly IRepository<Commodity> _commodityRepository;
        private readonly IRepository<CommodityShoppingOption> _commodityShoppingOptionRepository;
        private readonly IRepository<CommodityEvaluate> _commodityEvaluateRepository;
        private readonly IRepository<Member.Members.Member, long> _memberRepository;
        private readonly SalesPromotionManager _salesPromotionManager;
        private readonly SettingManager _settingManager;
        private readonly CollectionManager _collectionManager;

        public CommodityManager(
            IRepository<Commodity> commodityRepository,
            IRepository<CommodityShoppingOption> commodityShoppingOptionRepository,
            IRepository<CommodityEvaluate> commodityEvaluateRepository,
            IRepository<Member.Members.Member, long> memberRepository,
            SettingManager settingManager,
            SalesPromotionManager salesPromotionManager,
            CollectionManager collectionManager
            )
        {
            _commodityRepository = commodityRepository;
            _commodityShoppingOptionRepository = commodityShoppingOptionRepository;
            _commodityEvaluateRepository = commodityEvaluateRepository;
            _memberRepository = memberRepository;
            _settingManager = settingManager;
            _salesPromotionManager = salesPromotionManager;
            _collectionManager = collectionManager;
        }

        public async Task<Commodity> CreateCommodity(Commodity commodity, List<CommodityShoppingOption> commodityShoppingOptions)
        {
            await this.HandleCommodity(commodity, commodityShoppingOptions);

            int commodityId = await _commodityRepository.InsertAndGetIdAsync(commodity);
            if(commodity.IsEnabledShoppingOption)
            {
                foreach (var item in commodityShoppingOptions)
                {
                    item.CommodityId = commodityId;
                    await _commodityShoppingOptionRepository.InsertAsync(item);
                }
            }
            return commodity;
        }

        public async Task<Commodity> UpdateCommodity(Commodity commodity)
        {
            List<CommodityShoppingOption> commodityShoppingOptions = new List<CommodityShoppingOption>();
            if (commodity.IsEnabledShoppingOption)
            {
                commodityShoppingOptions = await GetCommodityShoppingOptions(commodity.Id);
            }

            await this.HandleCommodity(commodity, commodityShoppingOptions);

            return commodity;
        }

        public async Task HandleCommodity(Commodity commodity, List<CommodityShoppingOption> commodityShoppingOptions)
        {
            // 获取产品图片
            if (string.IsNullOrWhiteSpace(commodity.ShoppingInfo.Picture))
            {
                if (commodity.ShoppingInfo.Pictures.Items.Count > 0)
                {
                    commodity.ShoppingInfo.Picture = commodity.ShoppingInfo.Pictures.Items[0];
                }
                else if(commodity.IsEnabledShoppingOption)
                {
                    foreach (var item in commodityShoppingOptions)
                    {
                        if (item.Pictures.Items.Count > 0)
                        {
                            commodity.ShoppingInfo.Picture = item.Pictures.Items[0];
                            break;
                        }
                    }
                }
            }

            // 获取价格
            if (commodity.IsEnabledShoppingOption)
            {
                foreach (var item in commodityShoppingOptions)
                {
                    if (item.Price > commodity.ShoppingInfo.MaxPrice)
                    {
                        commodity.ShoppingInfo.MaxPrice = item.Price;
                    }
                    if (item.Price < commodity.ShoppingInfo.MinPrice)
                    {
                        commodity.ShoppingInfo.MinPrice = item.Price;
                    }
                }
            }
        }

        public async Task<Commodity> GetCommodity(int commodityId, bool mustBeShelved = false)
        {
            Commodity commodity = await _commodityRepository.FirstOrDefaultAsync(commodityId);
            if(commodity == null)
            {
                throw new UserFriendlyException("商品不存在");
            }
            if(mustBeShelved)
            {
                if(!commodity.Shelved)
                {
                    throw new UserFriendlyException("该商品已下架");
                }
            }
            return commodity;
        }

        /// <summary>
        /// 得到某个商品（某个购物选项）对于某个用户的产品价格等信息，这将很有用，例如产品列表，产品详情，购物车，收藏等等，都需要结合特定用户来显示具体信息
        /// </summary>
        /// <param name="member"></param>
        /// <param name="commodity"></param>
        /// <param name="commodityShoppingOption"></param>
        /// <returns></returns>
        public async Task<RealCommodity> GetRealCommodity(Member.Members.Member member, Commodity commodity, CommodityShoppingOption commodityShoppingOption = null)
        {
            RealCommodity realCommodity = new RealCommodity();
            realCommodity.Commodity = commodity;
            realCommodity.CommodityId = commodity.Id;
            realCommodity.CommodityName = commodity.Name;
            realCommodity.Shelved = commodity.Shelved;
            realCommodity.IsRecommended = commodity.IsRecommended;
            realCommodity.IsEnabledShoppingOption = commodity.IsEnabledShoppingOption;
            realCommodity.Discountable = commodity.Discountable;

            if (member != null)
            {
                realCommodity.IsForMember = true;
                realCommodity.Member = member;
                realCommodity.MemberId = member.Id;
                realCommodity.IsCollected = await _collectionManager.IsCollected(realCommodity.MemberId, realCommodity.CommodityId);
            }

            if (commodity.IsEnabledShoppingOption && commodityShoppingOption != null)
            {
                if (commodityShoppingOption.CommodityId != commodity.Id)
                {
                    throw new UserFriendlyException("购物选项不属于指定商品");
                }
                realCommodity.ShoppingOptionId = commodityShoppingOption.Id;
                realCommodity.CommodityShoppingOption = commodityShoppingOption;
                realCommodity.OriginalPrice = commodityShoppingOption.Price.Value;
                realCommodity.MinLimitCount = commodityShoppingOption.MinLimitCount;
                realCommodity.MaxLimitCount = commodityShoppingOption.MaxLimitCount;
                realCommodity.Picture = commodity.ShoppingInfo.GetValidPicture(commodityShoppingOption);
                realCommodity.Pictures = commodityShoppingOption.Pictures.Items;
                realCommodity.Inventory = commodityShoppingOption.Inventory;
                realCommodity.XPValue = commodityShoppingOption.XPValue;
                realCommodity.ShoppingOptionParameters = commodityShoppingOption.ShoppingOptionParameters;
            }
            else
            {
                realCommodity.OriginalPrice = commodity.ShoppingInfo.Price.Value;
                realCommodity.MinLimitCount = commodity.ShoppingInfo.MinLimitCount;
                realCommodity.MaxLimitCount = commodity.ShoppingInfo.MaxLimitCount;
                realCommodity.Picture = commodity.ShoppingInfo.GetValidPicture();
                realCommodity.Pictures = commodity.ShoppingInfo.Pictures.Items;
                realCommodity.Inventory = commodity.ShoppingInfo.Inventory;
                realCommodity.XPValue = commodity.ShoppingInfo.XPValue;
            }

            var promotions = await _salesPromotionManager.GetAllOfCommodity(commodity.Id, true);
            if (promotions.Count > 0)
            {
                // 限时活动不考虑打折
                var promotion = promotions[0];
                realCommodity.SalesPromotion = promotion;
                realCommodity.HasSalesPromotion = true;
                realCommodity.PromotionPrice = promotion.Price.Value;
            }
            else if (realCommodity.IsForMember && realCommodity.Discountable)
            {
                // 如果是会员，则计算折扣
                var discountMethod = _settingManager.GetDiscountMethod();
                var memberLevel = await _settingManager.GetMemberLevelByLevel(member.Level);
                if (discountMethod == DiscountMethod.Unified)
                {
                    // 统一设置折扣
                    realCommodity.Discount = memberLevel.Discount;
                }
                else if (discountMethod == DiscountMethod.Independent)
                {
                    // 各产品独立设置折扣
                    if (commodity.IsDiscountPerLevel)
                    {
                        // 每等级自定义折扣
                        if(commodity.Discounts.ContainsKey(member.Level))
                        {
                            realCommodity.Discount = commodity.Discounts[member.Level];
                        }
                        else
                        {
                            // 如果未设置等级折扣，则不折扣
                            realCommodity.Discount = 1;
                        }
                    }
                    else
                    {
                        // 使用统一折扣
                        realCommodity.Discount = memberLevel.Discount;
                    }
                }
            }

            return realCommodity;
        }
        
        public async Task<RealCommodity> GetRealCommodity(Member.Members.Member member, int commodityId, int? commodityShoppingOptionId, bool mustBeShelved = false)
        {
            Commodity commodity = await GetCommodity(commodityId, mustBeShelved);
            CommodityShoppingOption commodityShoppingOption = commodity.IsEnabledShoppingOption && commodityShoppingOptionId != null ?
                await GetCommodityShoppingOption((int)commodityShoppingOptionId) : null;
            return await GetRealCommodity(member, commodity, commodityShoppingOption);
        }

        public async Task<CommodityCollectionItem> GetCommodityCollectionItem(Member.Members.Member member, int count, int commodityId, int? commodityShoppingOptionId)
        {
            return new CommodityCollectionItem(count, await GetRealCommodity(member, commodityId, commodityShoppingOptionId));
        }

        public async Task<CommodityCollection> GetCommodityCollection(Member.Members.Member member, List<CommodityCollectionItem> items, MemberCoupon coupon = null, int xpValue = 0)
        {
            return new CommodityCollection(items, coupon, xpValue, member, _settingManager);
        }

        public Task DeleteCommodity(int commodityId)
        {
            Commodity commodity = _commodityRepository.Get(commodityId);

            if(commodity == null)
            {
                throw new UserFriendlyException("要删除的商品不存在");
            }

            return _commodityRepository.DeleteAsync(commodityId);
        }

        public async Task Shelved(int commodityId, bool value)
        {
            var item = await GetCommodity(commodityId);
            item.Shelved = value;
        }

        /// <summary>
        /// 库存变动
        /// </summary>
        /// <param name="commodityId"></param>
        /// <param name="shoppingOptionId"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public async Task ChangeInventory(int commodityId, int? shoppingOptionId, int count)
        {
            if(shoppingOptionId != null)
            {
                var item = await _commodityShoppingOptionRepository.FirstOrDefaultAsync((int)shoppingOptionId);
                if(item == null)
                {
                    // 说明购物选项已经被删除
                    return;
                }

                int result = item.Inventory + count;
                if(result < 0)
                {
                    throw new UserFriendlyException("库存量小于零");
                }
                item.Inventory = result;
            }
            else
            {
                var item = await _commodityRepository.FirstOrDefaultAsync(commodityId);
                if (item == null)
                {
                    // 说明商品已经被删除
                    return;
                }

                int result = item.ShoppingInfo.Inventory + count;
                if (result < 0)
                {
                    throw new UserFriendlyException("库存量小于零");
                }
                item.ShoppingInfo.Inventory = result;
            }
        }

        /// <summary>
        /// 销售量变动
        /// </summary>
        /// <param name="commodityId"></param>
        /// <param name="shoppingOptionId"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public async Task ChangeSalesVolume(int commodityId, int? shoppingOptionId, int count)
        {
            if (shoppingOptionId != null)
            {
                var item2 = await _commodityShoppingOptionRepository.FirstOrDefaultAsync((int)shoppingOptionId);
                if (item2 == null)
                {
                    // 说明购物选项已经被删除
                    return;
                }

                int result2 = item2.SalesVolume + count;
                if (result2 < 0)
                {
                    throw new UserFriendlyException("销量小于零");
                }
                item2.SalesVolume = result2;
            }

            var item = await _commodityRepository.FirstOrDefaultAsync(commodityId);
            if (item == null)
            {
                // 说明商品已经被删除
                return;
            }

            int result = item.ShoppingInfo.SalesVolume + count;
            if (result < 0)
            {
                throw new UserFriendlyException("销量小于零");
            }
            item.ShoppingInfo.SalesVolume = result;
        }

        #region 购物选项
        public async Task EnabledShoppingOption(int commodityId, bool value)
        {
            var item = await GetCommodity(commodityId);
            item.IsEnabledShoppingOption = value;
        }

        public async Task<CommodityShoppingOption> GetCommodityShoppingOption(int commodityShoppingOptionId)
        {
            return await _commodityShoppingOptionRepository.FirstOrDefaultAsync(commodityShoppingOptionId);
        }

        public async Task<List<CommodityShoppingOption>> GetCommodityShoppingOptions(int commodityId)
        {
            return _commodityShoppingOptionRepository.GetAll().Where(r => r.CommodityId == commodityId).ToList();
        }

        public async Task<CommodityShoppingOption> AddShoppingOption(Commodity commodity, CommodityShoppingOption commodityShoppingOption)
        {
            if (!commodity.IsEnabledShoppingOption)
            {
                throw new UserFriendlyException("该商品未开启购物选项");
            }
            commodityShoppingOption.CommodityId = commodity.Id;
            await _commodityShoppingOptionRepository.InsertAndGetIdAsync(commodityShoppingOption);
            return commodityShoppingOption;
        }

        public async Task<CommodityShoppingOption> UpdateShoppingOption(CommodityShoppingOption commodityShoppingOption)
        {
            await _commodityShoppingOptionRepository.UpdateAsync(commodityShoppingOption);
            return commodityShoppingOption;
        }

        public async Task DeleteShoppingOption(int shoppingOptionId)
        {
            await _commodityShoppingOptionRepository.DeleteAsync(shoppingOptionId);
        }
        #endregion
    }
}
